package samples.database;

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.ArrayList;

/**
 * This class is an example for a simple database connection pool which can be used in webserivices.
 */
public class SampleDatabaseManager
{
	private static final String	driver = "org.gjt.mm.mysql.Driver"; // In this sample we use a MySQL database
	private static final String	database = "jdbc:mysql://localhost/chemistry?user=myuser&password=mypassword";
	private static final int	poolSize = 5; // number of connections in the connection pool
	
	private static boolean	isInitialized = false;
	private static ArrayList	pool;

	/**
     * Initializes the connection pool.
     */
	public static void init()
		throws Exception
	{
		if(isInitialized) { return; }
		
		try {
			Class.forName(driver);
			
			pool = new ArrayList(poolSize);
			for(int i=0; i < poolSize; i++) {
				pool.add(newConnection());
			}	
		} catch (Exception e) {
			throw new Exception("Cannot connect to database!");	
		}
	
		isInitialized = true;
	}

	/**
     * Gets a new Connection.
     */
	public static Connection newConnection()
		throws Exception
	{
		return DriverManager.getConnection(database);
	}
	
	/**
     * Gets a connection from the connection pool or a new connection if the pool is empty.
     */
	public static Connection getConnection()
		throws Exception
	{
		if(!isInitialized) { throw new Exception("Not initialized!"); }
		
		Connection conn = null;
		if(pool.size() > 0)	{ conn = (Connection) pool.remove(0); }
		if(conn == null)	{ conn = newConnection(); }
		if(conn != null) 	{
			if(conn.isClosed()) { 
				freeConnection(conn);
				conn = newConnection();
			}
		}
		
		return conn;
	}
	
	/**
     * Puts the connection back into the connection pool.
     */
	public static void freeConnection(Connection conn)
		throws Exception	
	{
		if(!isInitialized) 	{ return; }
		if(conn == null)	{ conn = newConnection(); }
		if(pool.size() < poolSize) {
			if(conn.isClosed()) { pool.add(newConnection()); }
			else				{ pool.add(conn); }
		}
	}
	
	/**
     * Closes all connections.
     */
	public static void closeAll()
	{
		if(!isInitialized) { return; }
		
		while(pool.size() > 0) {
			try { ((Connection) pool.remove(0)).close(); }
			catch(Exception e) { }
		}
		
		isInitialized = false;
	}
	
}